#include "Graphics.h"

void Graphics::Init(SDL_PixelFormat* pixel_format)
{
    _pixel_format = pixel_format;
}

SDL_Surface* Graphics::NewSurface(const Point2D& size, Uint32 flags)
{
    return SDL_CreateRGBSurface
    (
        flags,size.GetX(),size.GetY(),
        _pixel_format->BitsPerPixel,
        _pixel_format->Rmask,
        _pixel_format->Gmask,
        _pixel_format->Bmask,
        _pixel_format->Amask
    );
}

SDL_Surface* Graphics::LoadImage(const char* filename)
{
    SDL_Surface* loaded_image = NULL;
    SDL_Surface* optimized_image = NULL;
    //loaded_image = SDL_LoadBMP(filename); // de SDL
    loaded_image = IMG_Load(filename);      // de la extension SDL_image carga BMP, PNM, XPM, LBM, PCX, GIF, JPEG, TGA y PNG
    if(loaded_image){
        optimized_image = SDL_DisplayFormat(loaded_image); // transforma al mismo formato que la screen, asi SDL no lo transforma auto. cada vez que hace blit (BMP es en 24 bit)
        SDL_FreeSurface(loaded_image);  // OJO! Ejecutar esto despues de setear el video mode (SDL_init). Sino tira segfault
        // hacer fondo transparente
        if(optimized_image){
            // Map the color key
            Uint32 colorkey = SDL_MapRGB(optimized_image->format,0,0xFF,0xFF);
            // Set all pixels of color R 0, G 0xFF, B 0xFF to be transparent
            SDL_SetColorKey(optimized_image,SDL_SRCCOLORKEY,colorkey);
        }
        else
        {
            printf("Graphics::LoadImage: optimized image couldnt be loaded");
        }
    }
    else
    {
        printf("Graphics::LoadImage: image %s could not be found.\n",filename);
    }

    return optimized_image;
}

Uint32 Graphics::GetColor(uint8 red, uint8 green, uint8 blue)
{
    return SDL_MapRGB(_pixel_format, red, green, blue);
}

Uint32 Graphics::GetColor(uint8 red, uint8 green, uint8 blue, uint8 alpha)
{
    return SDL_MapRGBA(_pixel_format, red, green, blue, alpha);
}

void Graphics::DrawPixel(SDL_Surface* surface, const Point2D& position, Uint32 color)
{
    Uint32* bufp = (Uint32 *)surface->pixels + position.GetY()*surface->pitch/4 + position.GetX();
    *bufp = color;
}

void Graphics::DrawLine(SDL_Surface* surface, const Point2D& src, const Point2D& dst, Uint32 color)
{
    if ( src.GetX() == dst.GetX() )
    
        if ( src.GetY() < dst.GetY()+1 )
            forsn ( j, src.GetY(), dst.GetY() )
                Graphics::DrawPixel(surface,Point2D(src.GetX(),j),color);
        
        else
            forsn ( j, dst.GetY(), src.GetY()+1 )
                Graphics::DrawPixel(surface,Point2D(src.GetX(),j),color);
    
    else if ( src.GetY() == dst.GetY() )
    
        if ( src.GetX() < dst.GetX()+1 )
            forsn ( i, src.GetX(), dst.GetX() )
                Graphics::DrawPixel(surface,Point2D(i,src.GetY()),color);
        
        else
            forsn ( i, dst.GetX(), src.GetX()+1 )
                Graphics::DrawPixel(surface,Point2D(i,src.GetY()),color);
}

SDL_PixelFormat* Graphics::_pixel_format = NULL;
